package top.jle.jpa.basic.exception;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serial;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;

/**
 * @author  jim.lee
 */
public class BasicCustomException extends RuntimeException {
	@Serial
	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER = LoggerFactory.getLogger(BasicCustomException.class);
    
    private final String code;
    
    private final JSONObject extension;

    public BasicCustomException(String code,JSONObject extension){
    	super(code);
    	this.code = code;
    	this.extension = extension;
	}
	public BasicCustomException(final String code){
		this(code,null);
	}

	public BasicCustomException(Enum<?> exceptionEnum){
		super(exceptionEnum.name());
		String exCode = exceptionEnum.name();
		Optional<Method> codeMethod = Arrays.stream(exceptionEnum.getClass().getDeclaredMethods()).filter(m->m.getName().equals("getCode")).findFirst();
		if (codeMethod.isPresent()) {
			JSON.mixIn(exceptionEnum.getClass(),ExceptionEnumJSONMixin.class);
			try {
				exCode = (String) codeMethod.get().invoke(exceptionEnum);
			} catch (Exception e) {
				LOGGER.error(e.getMessage(),e);
			}
			this.code = exCode;
			this.extension = JSONObject.from(exceptionEnum);
		}else{
			this.code = exceptionEnum.name();
			this.extension = null;
		}


	}
	public String getCode() {
		return this.code;
	}

	public JSONObject getExtension() {
		return extension;
	}

	@Override
	public String getMessage() {
		StringBuilder msg = new StringBuilder();
		msg.append(this.code);
		if(this.extension!=null && !this.extension.isEmpty()){
			msg.append(" ").append(this.extension.toJSONString());
		}
		return msg.toString();
	}

}
